use std::ops::Deref;
// 实现一个box
struct MyBox<T> (T);
impl <T> MyBox<T> {
    fn new(x: T) -> MyBox<T> {
        MyBox(x)
    }
}

// 自己实现的Box
// 说明一下，实现解引用只需要实现Deref这个trait就可以了
impl<T> Deref for MyBox<T> {
    type Target = T;
    fn deref(&self) -> &T {
        &self.0 // 为什么返回引用：不希望获得T的所有权
    }
}
// 实现一个函数
fn  hello(name: &str) {
    println!("Hello, {}!", name);
}

/// 解引用多态与可变性交互
/// - 当 T: Deref<Target=U>时，从 &T 到 &U
/// - 当 T: DerefMut<Target=U>时，从 &mut T 到 &mut U
/// - 当 T: Deref<Target=U>时，从 &mut T 到 U
fn main() {
    let s = MyBox::new(String::from("Rust"));
    hello(&s); // 将MyBox变为&string，再将String的解引用变为字符串slice（切片 &str），这个就叫解引用强制多态
    let x = 5;
    let y = MyBox::new(x);
    assert_eq!(x, 5);
    assert_eq!(*y, 5); // MyBox不能被解引用
}
